<template>
  <div class="circle-cropper">
    <!-- 上传按钮 -->
    <button v-if="!showCropper" class="upload-btn" @click="triggerFileInput">
      {{ uploadButtonText }}
      <input ref="fileInput" type="file" accept="image/*" hidden @change="handleFileChange" />
    </button>

    <!-- 裁剪区域 -->
    <div v-if="showCropper" class="cropper-container">
      <img ref="imageSrc" :src="imageUrl" alt="" />
      
      <div class="cropper-controls">
        <button class="cancel-btn" @click="cancelCrop">取消</button>
        <button class="confirm-btn" @click="confirmCrop">确认</button>
      </div>
    </div>

    <!-- 预览区域 -->
    <div v-if="previewUrl && !showCropper" class="result-preview">
      <img :src="previewUrl" alt="裁剪结果" />
    </div>
  </div>
</template>

<script>
import Cropper from 'cropperjs';
// import 'cropperjs/dist/cropper.css';

export default {
  name: 'CircleCropper',
  props: {
    // 上传按钮文字
    uploadButtonText: {
      type: String,
      default: '选择图片'
    },
    // 裁剪尺寸
    cropSize: {
      type: Number,
      default: 200
    }
  },
  data() {
    return {
      imageUrl: '',
      previewUrl: '',
      showCropper: false,
      cropper: null
    };
  },
  methods: {
    // 触发文件选择
    triggerFileInput() {
      this.$refs.fileInput.click();
    },
    
    // 处理文件选择
    handleFileChange(e) {
      const file = e.target.files[0];
      if (!file) return;
      
      // 读取文件并显示
      const reader = new FileReader();
      reader.onload = (event) => {
        this.imageUrl = event.target.result;
        this.showCropper = true;
        this.$nextTick(this.initCropper);
      };
      reader.readAsDataURL(file);
    },
    
    // 初始化裁剪器
    initCropper() {
      if (this.cropper) {
        this.cropper.destroy();
      }
      
      const image = this.$refs.imageSrc;
      this.cropper = new Cropper(image, {
        aspectRatio: 1,
        viewMode: 1,
        dragMode: 'move',
        autoCropArea: 0.8,
        guides: false,
        cropBoxResizable: false,
        toggleDragModeOnDblclick: false,
        minCropBoxWidth: this.cropSize,
        minCropBoxHeight: this.cropSize,
        ready: () => {
          // 设置固定大小的裁剪框
          const containerData = this.cropper.getContainerData();
          this.cropper.setCropBoxData({
            width: this.cropSize,
            height: this.cropSize,
            left: (containerData.width - this.cropSize) / 2,
            top: (containerData.height - this.cropSize) / 2
          });
        }
      });
    },
    
    // 确认裁剪
    confirmCrop() {
      if (!this.cropper) return;
      
      const canvas = this.cropper.getCroppedCanvas({
        width: this.cropSize,
        height: this.cropSize
      });
      
      // 获取裁剪结果
      this.previewUrl = canvas.toDataURL('image/jpeg', 0.9);
      
      // 发送裁剪结果给父组件
      this.$emit('crop-success', {
        dataUrl: this.previewUrl,
        blob: this.dataURLtoBlob(this.previewUrl)
      });
      
      // 关闭裁剪器
      this.showCropper = false;
      this.cropper.destroy();
      this.cropper = null;
    },
    
    // 取消裁剪
    cancelCrop() {
      this.showCropper = false;
      if (this.cropper) {
        this.cropper.destroy();
        this.cropper = null;
      }
    },
    
    // 将 Data URL 转换为 Blob 对象
    dataURLtoBlob(dataURL) {
      const arr = dataURL.split(',');
      const mime = arr[0].match(/:(.*?);/)[1];
      const bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      
      return new Blob([u8arr], { type: mime });
    }
  }
};
</script>

<style scoped>
.circle-cropper {
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
  padding: 15px;
}

.upload-btn {
  display: block;
  width: 80%;
  margin: 20px auto;
  padding: 12px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 25px;
  font-size: 16px;
  cursor: pointer;
}

.cropper-container {
  position: relative;
  width: 100%;
  margin: 15px 0;
}

.cropper-controls {
  display: flex;
  justify-content: space-around;
  margin-top: 15px;
}

.cancel-btn, .confirm-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 20px;
  font-size: 14px;
  cursor: pointer;
}

.cancel-btn {
  background: #6c757d;
  color: white;
}

.confirm-btn {
  background: #28a745;
  color: white;
}

.result-preview {
  width: 200px;
  height: 200px;
  margin: 20px auto;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.result-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 圆形裁剪框样式 */
:deep(.cropper-view-box),
:deep(.cropper-face) {
  border-radius: 50%;
  overflow: hidden;
}

/* 隐藏裁剪框的边角控制点 */
:deep(.cropper-line),
:deep(.cropper-point) {
  display: none;
}
</style>